什麼時候會用到自定義指令?除了原本的默認內置指令,雖然 Vue 的元件是可以複用的,但有時候我們仍然需要對普通 DOM 元素進行不同效果的操作,這時候就會用到自定義指令。在 Vue 內建的指令無法滿足需求或需要一個特別的功能時,就可以自己攥寫自定義指令,好處是可以重複使用。
自定義指定有兩種:全域自定義指令與局部的自定義指令。有時候我們在一個頁面裡可能會引入或增加好幾個 Vue 的實例,如果是全域的自定義指令,表示所有的 Vue 實例都可使用這個指令,但如果是局部自定義指令,需要指定能使用這組指令的 Vue 實例。
先來看 codepen :
Vue.Js Custom Directives 自定義指令
// Global 全域自定義指令 ps. directive 沒有 s
Vue.directive('my-directive', function (el, binding) {
el.innerHTML = binding.value.toupperCase();
});
// 局部的自定義指令 ps. directives 有 s
directives : {
'my-directive' : {
bind (el, binding) {
el.innerHTML = binding.value.toUpperCase()
}
}
// 也可以寫成
'my-directive'(el, binding) {
el.innerHTML = binding.value.toUpperCase()
}
}
在 HTML 的元素標籤上,直接以自定義的指令
<p v-my-directive = 'xxx';></p>
v-text
,功能是可將字串轉換成大寫,取名為v-upper-text
v-text
,功能是可將字串轉換成小寫,取名為v-lower-text
需要注意的是,我們自訂的指令名,並不包含v-
例如上述要實作的v-upper-text
,指令名為upper-text
,v-
一但定義了這些自定義的指令,在使用時就需要加上v-
。而只最終會被寫在 HTML 的元素標籤裡。
這個指令名會對應到一個「處理函式」,如以下範例的Vue.directive()
的第二參數
以下面的範例的 callback 函式來看,有兩個參數,第一個為el
表示使用這個指令的標籤,第二個參數binding
我們可以試著console.log()
出來觀察。
<div id="app1">
<p v-upper-text="msg1"></p>
<p v-lower-text="msg1"></p>
</div>
<div id="app2">
<p v-upper-text="msg2"></p>
<p v-lower-text="msg2"></p>
</div>
// 註冊定義全局指令
// el : 指令屬性的所在標籤物件
// binding : 包含指令相關訊息的資料物件
Vue.directive('upper-text', function (el, binding) {
console.log(el, binding);
// 把改變好的內容再指定回去
el.innerHTML = binding.value.toUpperCase();
});
const vm = new Vue({
el: '#app1',
data: {
msg1: 'Hello Paris',
},
// 註冊局部定義指令,只會對 #app1 這個實例有效
directives: {
'lower-text'(el, binding) {
el.innerHTML = binding.value.toLowerCase();
},
},
});
const vm = new Vue({
el: '#app2',
data: {
msg2: 'Hello Taipei',
},
});
在官網也提供一個很實用的範例,例如會員登入頁,我們希望使用者一進入頁面,不需將滑鼠移至輸入帳號的 input 框裡,而可直接輸入在輸入框裡,就可設一個全域的自定義的指令,這樣無論在哪一個登入頁面,只要需要先登入,就可使用這個 input 聚焦的指令在 input 裡,達到到達頁面可直接輸入內容的效果。
HTML 部分
<input v-focus>
JavaScript 部分
// 註冊一個全局自定義指令 `v-focus`
Vue.directive('focus', {
// 當被綁定的元素插入到 DOM 中時……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
// 如果想註冊局部指令,組件中也接受一個 directives 的選項:
directives: {
focus: {
// 指令的定義
inserted: function (el) {
el.focus()
}
}
}
每日一句法文有益身心:J'ai sommeil! --> 姐.艘妹! --> 我睏了!